Purpose

This work aims to develop sets of tools and procedures that will help trader to efficiently guess Financial Asset Market Type. Whether it’s a Bullish or Bearish Market, Ranging, Volatile - Author believes that having this ability to detect market type and use it in trading would be of a great advantage!

In order to test the approach Reinforcement Learning will be used. That is to identify which trading system works best in which market types.

Whenever this attempt fails, there would still be learning left! Reader would be still capable to know how to Use Deep Learning for Regression/Classification problems in combination with Reinforcement Learning

Task outlay

Basic idea of achieveing this will be:

Load packages

Note: follow https://www.h2o.ai/download/#h2o to install h2o on your computer

library(readr)
There were 50 or more warnings (use warnings() to see the first 50)
library(dplyr)
library(ggplot2)
library(lazytrade)
library(lubridate)
library(plotly)
library(h2o)

Data read

Here we can get into the financial data. Financial data can be read and refreshed using MQL side. How to do this is explained in the Udemy course. For the reproducibility purposes and for those who are not planning to trade sample data is available in the repository. It is either possible to reproduce or adapt code below to generate specific data or use data provided already.

Note: below code is optional. It is showing how to generate dataset to train the model. This data is also available inside R package ‘lazytrade’. See next section.

# ----------------------------------------------------------------------------------------
# R Script to select and train the Deep Learning model on Financial Asset Time Series Data
# ----------------------------------------------------------------------------------------
# ## Manually select data into big matrix with label of 6 classes
# ----------------------------------------------------------------------------------------
#

#### Read asset prices and indicators ==========================================
# load prices of 28 currencies
prices <- read_csv(file.path("inst/extdata", "AI_CP60-12000.csv"), col_names = F)
Parsed with column specification:
cols(
  .default = col_double(),
  X1 = col_character()
)
See spec(...) for full column specifications.
prices$X1 <- ymd_hms(prices$X1)
# load macd indicator of 28 currencies
macd <- read_csv(file.path("inst/extdata", "AI_Macd60-12000.csv"), col_names = F)
Parsed with column specification:
cols(
  .default = col_double(),
  X1 = col_character()
)
See spec(...) for full column specifications.
macd$X1 <- ymd_hms(macd$X1)

#### Manually Selecting data... =================================================
# Market Periods
# 1. Bull normal, BUN
# 2. Bull volatile, BUV
# 3. Bear normal, BEN
# 4. Bear volatile, BEV
# 5. Sideways quiet, RAN
# 6. Sideways volatile, RAV

##########################################################################
## ---------- # 1. Bull normal, BUN ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X5))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-01-01", X1 < "2018-01-20") %>% select(X1, X5)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X5))+geom_line()


# Extract corresponding piece of indicator dataframe:
macd_df <- macd %>% select(X1, X5) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X5.y, col = X5.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bun1 <- macd_df %>% select(X5.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X6))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-10-01", X1 < "2019-01-02") %>% select(X1, X6)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X6))+geom_line()


# Extract corresponding piece of indicator dataframe:
macd_df <- macd %>% select(X1, X6) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X6.y, col = X6.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bun2 <- macd_df %>% select(X6.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X7))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-02-20", X1 < "2018-04-15") %>% select(X1, X7)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X7))+geom_line()


# Extract corresponding piece of indicator dataframe:
macd_df <- macd %>% select(X1, X7) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X7.y, col = X7.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bun3 <- macd_df %>% select(X7.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X9))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-05-20", X1 < "2019-07-20") %>% select(X1, X9)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X9))+geom_line()


# Extract corresponding piece of indicator dataframe:
macd_df <- macd %>% select(X1, X9) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X9.y, col = X9.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bun4 <- macd_df %>% select(X9.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X24))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-01-10", X1 < "2019-03-02") %>% select(X1, X24)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X24))+geom_line()


# Extract corresponding piece of indicator dataframe:
macd_df <- macd %>% select(X1, X24) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X24.y, col = X24.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bun5 <- macd_df %>% select(X24.x) %>% to_m(64)
# --------------------

#########################################################################
# add new column to this matrix with value BUN
macd_m_bun1 <- transform(macd_m_bun1, M_T = "BUN")
macd_m_bun2 <- transform(macd_m_bun2, M_T = "BUN")
macd_m_bun3 <- transform(macd_m_bun3, M_T = "BUN")
macd_m_bun4 <- transform(macd_m_bun4, M_T = "BUN")
macd_m_bun5 <- transform(macd_m_bun5, M_T = "BUN")
##########################################################################


##########################################################################
## ---------- # 2. Bull volatile, BUV ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X6))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-02-19", X1 < "2018-03-20") %>% select(X1, X6)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X6))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X6) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X6.y, col = X6.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv1 <- macd_df %>% select(X6.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X7))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-04-18", X1 < "2018-05-10") %>% select(X1, X7)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X7))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X7) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X7.y, col = X7.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv2 <- macd_df %>% select(X7.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X9))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-05-08", X1 < "2019-05-20") %>% select(X1, X9)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X9))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X9) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X9.y, col = X9.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv3 <- macd_df %>% select(X9.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X11))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-04-01", X1 < "2019-04-22") %>% select(X1, X11)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X11))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X11) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X11.y, col = X11.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv4 <- macd_df %>% select(X11.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X12))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-07-23", X1 < "2019-08-07") %>% select(X1, X12)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X12))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X12) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X12.y, col = X12.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv5 <- macd_df %>% select(X12.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X14))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-08-20", X1 < "2018-09-07") %>% select(X1, X14)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X14))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X14) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X14.y, col = X14.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv6 <- macd_df %>% select(X14.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X14))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-07-20", X1 < "2019-08-07") %>% select(X1, X14)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X14))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X14) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X14.y, col = X14.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv7 <- macd_df %>% select(X14.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X15))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-03-13", X1 < "2018-03-23") %>% select(X1, X15)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X15))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X15) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X15.y, col = X15.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv8 <- macd_df %>% select(X15.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X23))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-03-23", X1 < "2019-04-23") %>% select(X1, X23)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X23))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X23) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X23.y, col = X23.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_buv9 <- macd_df %>% select(X23.x) %>% to_m(64)
# --------------------

#########################################################################
macd_m_buv1 <- transform(macd_m_buv1, M_T = "BUV") 
macd_m_buv2 <- transform(macd_m_buv2, M_T = "BUV")
macd_m_buv3 <- transform(macd_m_buv3, M_T = "BUV") 
macd_m_buv4 <- transform(macd_m_buv4, M_T = "BUV") 
macd_m_buv5 <- transform(macd_m_buv5, M_T = "BUV")
macd_m_buv6 <- transform(macd_m_buv6, M_T = "BUV")
macd_m_buv7 <- transform(macd_m_buv7, M_T = "BUV")
macd_m_buv8 <- transform(macd_m_buv8, M_T = "BUV")
macd_m_buv9 <- transform(macd_m_buv9, M_T = "BUV") 
#########################################################################


##########################################################################
## ---------- # 3. Bear normal, BEN ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X3))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-11-19", X1 < "2018-12-15") %>% select(X1, X3)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X3))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X3) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X3.y, col = X3.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ben1 <- macd_df %>% select(X3.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X5))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-03-19", X1 < "2019-06-01") %>% select(X1, X5)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X5))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X5) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X5.y, col = X5.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ben2 <- macd_df %>% select(X5.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X10))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-04-19", X1 < "2019-06-01") %>% select(X1, X10)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X10))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X10) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X10.y, col = X10.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ben3 <- macd_df %>% select(X10.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X11))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-05-10", X1 < "2019-06-01") %>% select(X1, X11)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X11))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X11) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X11.y, col = X11.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ben4 <- macd_df %>% select(X11.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X17))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-05-20", X1 < "2019-07-20") %>% select(X1, X17)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X17))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X17) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X17.y, col = X17.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ben5 <- macd_df %>% select(X17.x) %>% to_m(64)
# --------------------

#########################################################################
macd_m_ben1 <- transform(macd_m_ben1, M_T = "BEN")
macd_m_ben2 <- transform(macd_m_ben2, M_T = "BEN")
macd_m_ben3 <- transform(macd_m_ben3, M_T = "BEN")
macd_m_ben4 <- transform(macd_m_ben4, M_T = "BEN")
macd_m_ben5 <- transform(macd_m_ben5, M_T = "BEN")

#########################################################################


##########################################################################
## ---------- # 4. Bear volatile, BEV ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X2))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-04-22", X1 < "2018-05-10") %>% select(X1, X2)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X2))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X2) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X2.y, col = X2.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev1 <- macd_df %>% select(X2.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X3))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-04-22", X1 < "2018-05-05") %>% select(X1, X3)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X3))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X3) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X3.y, col = X3.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev2 <- macd_df %>% select(X3.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X11))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-05-15", X1 < "2018-06-01") %>% select(X1, X11)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X11))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X11) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X11.y, col = X11.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev3 <- macd_df %>% select(X11.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X12))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-10-15", X1 < "2018-11-01") %>% select(X1, X12)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X12))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X12) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X12.y, col = X12.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev4 <- macd_df %>% select(X12.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X13))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-03-15", X1 < "2018-04-15") %>% select(X1, X13)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X13))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X13) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X13.y, col = X13.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev5 <- macd_df %>% select(X13.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X16))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2019-05-13", X1 < "2019-05-23") %>% select(X1, X16)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X16))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X16) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X16.y, col = X16.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev6 <- macd_df %>% select(X16.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X24))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-02-05", X1 < "2018-02-19") %>% select(X1, X24)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X24))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X24) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X24.y, col = X24.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_bev7 <- macd_df %>% select(X24.x) %>% to_m(64)
# --------------------
#########################################################################
macd_m_bev1 <- transform(macd_m_bev1, M_T = "BEV")
macd_m_bev2 <- transform(macd_m_bev2, M_T = "BEV")
macd_m_bev3 <- transform(macd_m_bev3, M_T = "BEV")
macd_m_bev4 <- transform(macd_m_bev4, M_T = "BEV")
macd_m_bev5 <- transform(macd_m_bev5, M_T = "BEV")
macd_m_bev6 <- transform(macd_m_bev6, M_T = "BEV")
macd_m_bev7 <- transform(macd_m_bev7, M_T = "BEV")
#########################################################################


##########################################################################
## ---------- # 5. Sideways quiet, RAN ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X2))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-02-20", X1 < "2018-04-10") %>% select(X1, X2)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X2))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X2) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X2.y, col = X2.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ran1 <- macd_df %>% select(X2.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X4))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-07-01", X1 < "2018-08-10") %>% select(X1, X4)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X4))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X4) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X4.y, col = X4.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ran2 <- macd_df %>% select(X4.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X9))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-06-25", X1 < "2018-07-10") %>% select(X1, X9)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X9))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X9) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X9.y, col = X9.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ran3 <- macd_df %>% select(X9.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X12))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-06-25", X1 < "2018-07-10") %>% select(X1, X9)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X9))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X9) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X9.y, col = X9.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_ran3 <- macd_df %>% select(X9.x) %>% to_m(64)
# --------------------
#########################################################################
macd_m_ran1 <- transform(macd_m_ran1, M_T = "RAN") 
macd_m_ran2 <- transform(macd_m_ran2, M_T = "RAN") 
macd_m_ran3 <- transform(macd_m_ran3, M_T = "RAN") 
#########################################################################

##########################################################################
## ---------- # 6. Sideways volatile, RAV ---------------
##########################################################################
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X2))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2018-02-01", X1 < "2018-04-01") %>% select(X1, X2)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X2))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X2) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X2.y, col = X2.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_rav1 <- macd_df %>% select(X2.x) %>% to_m(64)
# --------------------
# --------------------
# Choose the asset corresponding to this period /find by replacing 'y' argument/
ggplot(prices, aes(X1, X9))+geom_line()


# Extract approximate date and choose only relevant columns
price_df <- prices %>% filter(X1 > "2017-11-01", X1 < "2017-12-01") %>% select(X1, X9)

# Visualize it to confirm 
ggplot(price_df, aes(X1, X9))+geom_line()


# Extract corresponding piece of macd dataframe:
macd_df <- macd %>% select(X1, X9) %>% inner_join(price_df, by = c("X1" = "X1"))

# Visualize both things together
ggplot(macd_df, aes(X1, X9.y, col = X9.x))+geom_line()


# transform to matrix, number of columns will correspond to model sensitivity e.g. 100 columns ~ 24 Hours
macd_m_rav2 <- macd_df %>% select(X9.x) %>% to_m(64)
# --------------------

#########################################################################
macd_m_rav1 <- transform(macd_m_rav1, M_T = "RAV")
macd_m_rav2 <- transform(macd_m_rav2, M_T = "RAV")
#########################################################################
#########################################################################
#########################################################################

# Combine all of that :)
macd_ML2 <- rbind(macd_m_bun1,macd_m_bun2,macd_m_bun3,macd_m_bun4,macd_m_bun5,
                  macd_m_buv1,macd_m_buv2,macd_m_buv3,macd_m_buv4,macd_m_buv5,macd_m_buv6,macd_m_buv7,macd_m_buv8,macd_m_buv9,
                  macd_m_ben1,macd_m_ben2,macd_m_ben3,macd_m_ben4,macd_m_ben5,
                  macd_m_bev1,macd_m_bev2,macd_m_bev3,macd_m_bev4,macd_m_bev5,macd_m_bev6,macd_m_bev7,
                  macd_m_ran1,macd_m_ran2,macd_m_ran3,
                  macd_m_rav1,macd_m_rav2)

### NOTE Number of rows Matrices needs to be roughly equal

# Optionally record data into the folder
if(!dir.exists(file.path(getwd(),"_DATA/data_initial"))){
  dir.create(file.path(getwd(),"_DATA/data_initial"))
  write_rds(macd_ML2, file.path(getwd(),"_DATA/data_initial", "macd_ML2.rds"))
}
  

## Visualize new matrix in 3D
plot_ly(z = as.matrix(macd_ML2[,1:64]), type = "surface")


#### End

Generate model

Folder _PROD contains script 02_BuildModel.R that can be used to build a model

Classify current market type

Folder _PROD contains script 03_Score_Data.R that can be used to score new data

Conclusion

Scripts could be automated to run and predict current market type. In many occasions confidence of predictions will be low this can be used to filter bad predictions

LS0tDQp0aXRsZTogIkRldGVjdCBNYXJrZXQgc3RhdHVzIHdpdGggQUkiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyBQdXJwb3NlDQoNClRoaXMgd29yayBhaW1zIHRvIGRldmVsb3Agc2V0cyBvZiB0b29scyBhbmQgcHJvY2VkdXJlcyB0aGF0IHdpbGwgaGVscCB0cmFkZXIgdG8gZWZmaWNpZW50bHkgZ3Vlc3MgRmluYW5jaWFsIEFzc2V0IE1hcmtldCBUeXBlLiBXaGV0aGVyIGl0J3MgYSBCdWxsaXNoIG9yIEJlYXJpc2ggTWFya2V0LCBSYW5naW5nLCBWb2xhdGlsZSAtIEF1dGhvciBiZWxpZXZlcyB0aGF0IGhhdmluZyB0aGlzIGFiaWxpdHkgdG8gZGV0ZWN0IG1hcmtldCB0eXBlIGFuZCB1c2UgaXQgaW4gdHJhZGluZyB3b3VsZCBiZSBvZiBhIGdyZWF0IGFkdmFudGFnZSENCg0KSW4gb3JkZXIgdG8gdGVzdCB0aGUgYXBwcm9hY2ggUmVpbmZvcmNlbWVudCBMZWFybmluZyB3aWxsIGJlIHVzZWQuIFRoYXQgaXMgdG8gaWRlbnRpZnkgd2hpY2ggdHJhZGluZyBzeXN0ZW0gd29ya3MgYmVzdCBpbiB3aGljaCBtYXJrZXQgdHlwZXMuDQoNCldoZW5ldmVyIHRoaXMgYXR0ZW1wdCBmYWlscywgdGhlcmUgd291bGQgc3RpbGwgYmUgbGVhcm5pbmcgbGVmdCEgUmVhZGVyIHdvdWxkIGJlIHN0aWxsIGNhcGFibGUgdG8ga25vdyBob3cgdG8gKipVc2UgRGVlcCBMZWFybmluZyBmb3IgUmVncmVzc2lvbi9DbGFzc2lmaWNhdGlvbiBwcm9ibGVtcyBpbiBjb21iaW5hdGlvbiB3aXRoIFJlaW5mb3JjZW1lbnQgTGVhcm5pbmcqKg0KDQojIyBUYXNrIG91dGxheQ0KDQpCYXNpYyBpZGVhIG9mIGFjaGlldmVpbmcgdGhpcyB3aWxsIGJlOg0KDQotIE1hbnVhbGx5IGNsYXNzaWZ5IGRhdGEgZnJvbSBmb3JleCBwYWlycyBpbnRvIHBlcmlvZHMgb2Ygc3BlY2lmaWMgbWFya2V0IHBlcmlvZHMNCi0gRXh0cmFjdCBNQUNEIGluZGljYXRvciAob3IgYW55IG90aGVyIGluZGljYXRvcikgY29ycmVzcG9uZGluZyB0byB0aGUgcGVyaW9kcw0KLSBDcmVhdGUgY29tYmluZWQgZGF0YXNldCB3aXRoIGNsYXNzaWZpZWQgZGF0YQ0KLSBGaXQgQ2xhc3NpZmljYXRpb24gTk4gbW9kZWwNCi0gUHJvZHVjdGlvbml6ZSBtb2RlbCBmb3IgdGhlIG5ldyBjb21pbmcgZGF0YQ0KLSBSZWNvcmQgbW9yZSBuZXcgZGF0YSBvbmNlIHRoZSBtb2RlbCBwcmVkaWN0cyBtYXJrZXQgdHlwZXMgd2l0aCBhIHZlcnkgaGlnaCBjb25maWRlbmNlDQotIEluIE1RTCBzaWRlOg0KICAgIC0gcmVjb3JkIG1hcmtldCB0eXBlIG9uY2UgbmV3IG9yZGVyIGlzIHBsYWNlZA0KICAgIC0gdXNlIHJlaW5mb3JjZW1lbnQgbGVhcm5pbmcgdG8gZGVmaW5lIGEgcG9saWN5IGZvciBlYWNoIG1hcmtldCB0eXBlDQotIFdlZWtseSB1cGRhdGUgdGhlIG1vZGVsIHdpdGggbmV3IGRhdGENCg0KIyMgTG9hZCBwYWNrYWdlcw0KDQpOb3RlOiBmb2xsb3cgaHR0cHM6Ly93d3cuaDJvLmFpL2Rvd25sb2FkLyNoMm8gdG8gaW5zdGFsbCBoMm8gb24geW91ciBjb21wdXRlcg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsYXp5dHJhZGUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShoMm8pDQpgYGANCg0KIyMgRGF0YSByZWFkDQoNCkhlcmUgd2UgY2FuIGdldCBpbnRvIHRoZSBmaW5hbmNpYWwgZGF0YS4gRmluYW5jaWFsIGRhdGEgY2FuIGJlIHJlYWQgYW5kIHJlZnJlc2hlZCB1c2luZyBNUUwgc2lkZS4gSG93IHRvIGRvIHRoaXMgaXMgZXhwbGFpbmVkIGluIHRoZSBVZGVteSBjb3Vyc2UuIEZvciB0aGUgcmVwcm9kdWNpYmlsaXR5IHB1cnBvc2VzIGFuZCBmb3IgdGhvc2Ugd2hvIGFyZSBub3QgcGxhbm5pbmcgdG8gdHJhZGUgc2FtcGxlIGRhdGEgaXMgYXZhaWxhYmxlIGluIHRoZSByZXBvc2l0b3J5LiBJdCBpcyBlaXRoZXIgcG9zc2libGUgdG8gcmVwcm9kdWNlIG9yIGFkYXB0IGNvZGUgYmVsb3cgdG8gZ2VuZXJhdGUgc3BlY2lmaWMgZGF0YSBvciB1c2UgZGF0YSBwcm92aWRlZCBhbHJlYWR5Lg0KDQpOb3RlOiBiZWxvdyBjb2RlIGlzIG9wdGlvbmFsLiBJdCBpcyBzaG93aW5nIGhvdyB0byBnZW5lcmF0ZSBkYXRhc2V0IHRvIHRyYWluIHRoZSBtb2RlbC4gVGhpcyBkYXRhIGlzIGFsc28gYXZhaWxhYmxlIGluc2lkZSBSIHBhY2thZ2UgJ2xhenl0cmFkZScuIFNlZSBuZXh0IHNlY3Rpb24uDQoNCmBgYHtyfQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFIgU2NyaXB0IHRvIHNlbGVjdCBhbmQgdHJhaW4gdGhlIERlZXAgTGVhcm5pbmcgbW9kZWwgb24gRmluYW5jaWFsIEFzc2V0IFRpbWUgU2VyaWVzIERhdGENCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAjIyBNYW51YWxseSBzZWxlY3QgZGF0YSBpbnRvIGJpZyBtYXRyaXggd2l0aCBsYWJlbCBvZiA2IGNsYXNzZXMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIw0KDQojIyMjIFJlYWQgYXNzZXQgcHJpY2VzIGFuZCBpbmRpY2F0b3JzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KIyBsb2FkIHByaWNlcyBvZiAyOCBjdXJyZW5jaWVzDQpwcmljZXMgPC0gcmVhZF9jc3YoZmlsZS5wYXRoKCJpbnN0L2V4dGRhdGEiLCAiQUlfQ1A2MC0xMjAwMC5jc3YiKSwgY29sX25hbWVzID0gRikNCnByaWNlcyRYMSA8LSB5bWRfaG1zKHByaWNlcyRYMSkNCiMgbG9hZCBtYWNkIGluZGljYXRvciBvZiAyOCBjdXJyZW5jaWVzDQptYWNkIDwtIHJlYWRfY3N2KGZpbGUucGF0aCgiaW5zdC9leHRkYXRhIiwgIkFJX01hY2Q2MC0xMjAwMC5jc3YiKSwgY29sX25hbWVzID0gRikNCm1hY2QkWDEgPC0geW1kX2htcyhtYWNkJFgxKQ0KDQojIyMjIE1hbnVhbGx5IFNlbGVjdGluZyBkYXRhLi4uID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgTWFya2V0IFBlcmlvZHMNCiMgMS4gQnVsbCBub3JtYWwsIEJVTg0KIyAyLiBCdWxsIHZvbGF0aWxlLCBCVVYNCiMgMy4gQmVhciBub3JtYWwsIEJFTg0KIyA0LiBCZWFyIHZvbGF0aWxlLCBCRVYNCiMgNS4gU2lkZXdheXMgcXVpZXQsIFJBTg0KIyA2LiBTaWRld2F5cyB2b2xhdGlsZSwgUkFWDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyAtLS0tLS0tLS0tICMgMS4gQnVsbCBub3JtYWwsIEJVTiAtLS0tLS0tLS0tLS0tLS0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYNSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTAxLTAxIiwgWDEgPCAiMjAxOC0wMS0yMCIpICU+JSBzZWxlY3QoWDEsIFg1KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg1KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgaW5kaWNhdG9yIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYNSkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYNS55LCBjb2wgPSBYNS54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnVuMSA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDUueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYNikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTEwLTAxIiwgWDEgPCAiMjAxOS0wMS0wMiIpICU+JSBzZWxlY3QoWDEsIFg2KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg2KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgaW5kaWNhdG9yIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYNikgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYNi55LCBjb2wgPSBYNi54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnVuMiA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDYueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYNykpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTAyLTIwIiwgWDEgPCAiMjAxOC0wNC0xNSIpICU+JSBzZWxlY3QoWDEsIFg3KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg3KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgaW5kaWNhdG9yIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYNykgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYNy55LCBjb2wgPSBYNy54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnVuMyA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDcueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYOSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE5LTA1LTIwIiwgWDEgPCAiMjAxOS0wNy0yMCIpICU+JSBzZWxlY3QoWDEsIFg5KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg5KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgaW5kaWNhdG9yIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYOSkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYOS55LCBjb2wgPSBYOS54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnVuNCA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDkueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMjQpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOS0wMS0xMCIsIFgxIDwgIjIwMTktMDMtMDIiKSAlPiUgc2VsZWN0KFgxLCBYMjQpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDI0KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgaW5kaWNhdG9yIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMjQpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDI0LnksIGNvbCA9IFgyNC54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnVuNSA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDI0LngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIGFkZCBuZXcgY29sdW1uIHRvIHRoaXMgbWF0cml4IHdpdGggdmFsdWUgQlVODQptYWNkX21fYnVuMSA8LSB0cmFuc2Zvcm0obWFjZF9tX2J1bjEsIE1fVCA9ICJCVU4iKQ0KbWFjZF9tX2J1bjIgPC0gdHJhbnNmb3JtKG1hY2RfbV9idW4yLCBNX1QgPSAiQlVOIikNCm1hY2RfbV9idW4zIDwtIHRyYW5zZm9ybShtYWNkX21fYnVuMywgTV9UID0gIkJVTiIpDQptYWNkX21fYnVuNCA8LSB0cmFuc2Zvcm0obWFjZF9tX2J1bjQsIE1fVCA9ICJCVU4iKQ0KbWFjZF9tX2J1bjUgPC0gdHJhbnNmb3JtKG1hY2RfbV9idW41LCBNX1QgPSAiQlVOIikNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIC0tLS0tLS0tLS0gIyAyLiBCdWxsIHZvbGF0aWxlLCBCVVYgLS0tLS0tLS0tLS0tLS0tDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDYpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wMi0xOSIsIFgxIDwgIjIwMTgtMDMtMjAiKSAlPiUgc2VsZWN0KFgxLCBYNikNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYNikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFg2KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFg2LnksIGNvbCA9IFg2LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9idXYxIDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYNi54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFg3KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTgtMDQtMTgiLCBYMSA8ICIyMDE4LTA1LTEwIikgJT4lIHNlbGVjdChYMSwgWDcpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDcpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYNykgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYNy55LCBjb2wgPSBYNy54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnV2MiA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDcueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYOSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE5LTA1LTA4IiwgWDEgPCAiMjAxOS0wNS0yMCIpICU+JSBzZWxlY3QoWDEsIFg5KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg5KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDkpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDkueSwgY29sID0gWDkueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2J1djMgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFg5LngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDExKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTktMDQtMDEiLCBYMSA8ICIyMDE5LTA0LTIyIikgJT4lIHNlbGVjdChYMSwgWDExKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgxMSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgxMSkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMTEueSwgY29sID0gWDExLngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9idXY0IDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMTEueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMTIpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOS0wNy0yMyIsIFgxIDwgIjIwMTktMDgtMDciKSAlPiUgc2VsZWN0KFgxLCBYMTIpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDEyKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDEyKSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFgxMi55LCBjb2wgPSBYMTIueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2J1djUgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgxMi54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgxNCkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTA4LTIwIiwgWDEgPCAiMjAxOC0wOS0wNyIpICU+JSBzZWxlY3QoWDEsIFgxNCkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMTQpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMTQpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDE0LnksIGNvbCA9IFgxNC54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnV2NiA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDE0LngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDE0KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTktMDctMjAiLCBYMSA8ICIyMDE5LTA4LTA3IikgJT4lIHNlbGVjdChYMSwgWDE0KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgxNCkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgxNCkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMTQueSwgY29sID0gWDE0LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9idXY3IDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMTQueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMTUpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wMy0xMyIsIFgxIDwgIjIwMTgtMDMtMjMiKSAlPiUgc2VsZWN0KFgxLCBYMTUpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDE1KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDE1KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFgxNS55LCBjb2wgPSBYMTUueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2J1djggPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgxNS54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgyMykpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE5LTAzLTIzIiwgWDEgPCAiMjAxOS0wNC0yMyIpICU+JSBzZWxlY3QoWDEsIFgyMykNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMjMpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMjMpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDIzLnksIGNvbCA9IFgyMy54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYnV2OSA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDIzLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQptYWNkX21fYnV2MSA8LSB0cmFuc2Zvcm0obWFjZF9tX2J1djEsIE1fVCA9ICJCVVYiKSANCm1hY2RfbV9idXYyIDwtIHRyYW5zZm9ybShtYWNkX21fYnV2MiwgTV9UID0gIkJVViIpDQptYWNkX21fYnV2MyA8LSB0cmFuc2Zvcm0obWFjZF9tX2J1djMsIE1fVCA9ICJCVVYiKSANCm1hY2RfbV9idXY0IDwtIHRyYW5zZm9ybShtYWNkX21fYnV2NCwgTV9UID0gIkJVViIpIA0KbWFjZF9tX2J1djUgPC0gdHJhbnNmb3JtKG1hY2RfbV9idXY1LCBNX1QgPSAiQlVWIikNCm1hY2RfbV9idXY2IDwtIHRyYW5zZm9ybShtYWNkX21fYnV2NiwgTV9UID0gIkJVViIpDQptYWNkX21fYnV2NyA8LSB0cmFuc2Zvcm0obWFjZF9tX2J1djcsIE1fVCA9ICJCVVYiKQ0KbWFjZF9tX2J1djggPC0gdHJhbnNmb3JtKG1hY2RfbV9idXY4LCBNX1QgPSAiQlVWIikNCm1hY2RfbV9idXY5IDwtIHRyYW5zZm9ybShtYWNkX21fYnV2OSwgTV9UID0gIkJVViIpIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyAtLS0tLS0tLS0tICMgMy4gQmVhciBub3JtYWwsIEJFTiAtLS0tLS0tLS0tLS0tLS0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMykpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTExLTE5IiwgWDEgPCAiMjAxOC0xMi0xNSIpICU+JSBzZWxlY3QoWDEsIFgzKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgzKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDMpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDMueSwgY29sID0gWDMueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2JlbjEgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgzLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDUpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOS0wMy0xOSIsIFgxIDwgIjIwMTktMDYtMDEiKSAlPiUgc2VsZWN0KFgxLCBYNSkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYNSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFg1KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFg1LnksIGNvbCA9IFg1LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9iZW4yIDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYNS54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgxMCkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE5LTA0LTE5IiwgWDEgPCAiMjAxOS0wNi0wMSIpICU+JSBzZWxlY3QoWDEsIFgxMCkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMTApKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMTApICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDEwLnksIGNvbCA9IFgxMC54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYmVuMyA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDEwLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDExKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTktMDUtMTAiLCBYMSA8ICIyMDE5LTA2LTAxIikgJT4lIHNlbGVjdChYMSwgWDExKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgxMSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgxMSkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMTEueSwgY29sID0gWDExLngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9iZW40IDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMTEueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMTcpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOS0wNS0yMCIsIFgxIDwgIjIwMTktMDctMjAiKSAlPiUgc2VsZWN0KFgxLCBYMTcpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDE3KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDE3KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFgxNy55LCBjb2wgPSBYMTcueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2JlbjUgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgxNy54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KbWFjZF9tX2JlbjEgPC0gdHJhbnNmb3JtKG1hY2RfbV9iZW4xLCBNX1QgPSAiQkVOIikNCm1hY2RfbV9iZW4yIDwtIHRyYW5zZm9ybShtYWNkX21fYmVuMiwgTV9UID0gIkJFTiIpDQptYWNkX21fYmVuMyA8LSB0cmFuc2Zvcm0obWFjZF9tX2JlbjMsIE1fVCA9ICJCRU4iKQ0KbWFjZF9tX2JlbjQgPC0gdHJhbnNmb3JtKG1hY2RfbV9iZW40LCBNX1QgPSAiQkVOIikNCm1hY2RfbV9iZW41IDwtIHRyYW5zZm9ybShtYWNkX21fYmVuNSwgTV9UID0gIkJFTiIpDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgLS0tLS0tLS0tLSAjIDQuIEJlYXIgdm9sYXRpbGUsIEJFViAtLS0tLS0tLS0tLS0tLS0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTA0LTIyIiwgWDEgPCAiMjAxOC0wNS0xMCIpICU+JSBzZWxlY3QoWDEsIFgyKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgyKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDIpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDIueSwgY29sID0gWDIueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2JldjEgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgyLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDMpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wNC0yMiIsIFgxIDwgIjIwMTgtMDUtMDUiKSAlPiUgc2VsZWN0KFgxLCBYMykNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMykpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgzKSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFgzLnksIGNvbCA9IFgzLngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9iZXYyIDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMy54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgxMSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTA1LTE1IiwgWDEgPCAiMjAxOC0wNi0wMSIpICU+JSBzZWxlY3QoWDEsIFgxMSkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMTEpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMTEpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDExLnksIGNvbCA9IFgxMS54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYmV2MyA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDExLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDEyKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTgtMTAtMTUiLCBYMSA8ICIyMDE4LTExLTAxIikgJT4lIHNlbGVjdChYMSwgWDEyKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgxMikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgxMikgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMTIueSwgY29sID0gWDEyLngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9iZXY0IDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMTIueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMTMpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wMy0xNSIsIFgxIDwgIjIwMTgtMDQtMTUiKSAlPiUgc2VsZWN0KFgxLCBYMTMpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDEzKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDEzKSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFgxMy55LCBjb2wgPSBYMTMueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX2JldjUgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgxMy54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgxNikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE5LTA1LTEzIiwgWDEgPCAiMjAxOS0wNS0yMyIpICU+JSBzZWxlY3QoWDEsIFgxNikNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYMTYpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMTYpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDE2LnksIGNvbCA9IFgxNi54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fYmV2NiA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDE2LngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDI0KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTgtMDItMDUiLCBYMSA8ICIyMDE4LTAyLTE5IikgJT4lIHNlbGVjdChYMSwgWDI0KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgyNCkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFgyNCkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMjQueSwgY29sID0gWDI0LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9iZXY3IDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYMjQueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQptYWNkX21fYmV2MSA8LSB0cmFuc2Zvcm0obWFjZF9tX2JldjEsIE1fVCA9ICJCRVYiKQ0KbWFjZF9tX2JldjIgPC0gdHJhbnNmb3JtKG1hY2RfbV9iZXYyLCBNX1QgPSAiQkVWIikNCm1hY2RfbV9iZXYzIDwtIHRyYW5zZm9ybShtYWNkX21fYmV2MywgTV9UID0gIkJFViIpDQptYWNkX21fYmV2NCA8LSB0cmFuc2Zvcm0obWFjZF9tX2JldjQsIE1fVCA9ICJCRVYiKQ0KbWFjZF9tX2JldjUgPC0gdHJhbnNmb3JtKG1hY2RfbV9iZXY1LCBNX1QgPSAiQkVWIikNCm1hY2RfbV9iZXY2IDwtIHRyYW5zZm9ybShtYWNkX21fYmV2NiwgTV9UID0gIkJFViIpDQptYWNkX21fYmV2NyA8LSB0cmFuc2Zvcm0obWFjZF9tX2JldjcsIE1fVCA9ICJCRVYiKQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyAtLS0tLS0tLS0tICMgNS4gU2lkZXdheXMgcXVpZXQsIFJBTiAtLS0tLS0tLS0tLS0tLS0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMikpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE4LTAyLTIwIiwgWDEgPCAiMjAxOC0wNC0xMCIpICU+JSBzZWxlY3QoWDEsIFgyKQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFgyKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDIpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDIueSwgY29sID0gWDIueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX3JhbjEgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFgyLngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBDaG9vc2UgdGhlIGFzc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBwZXJpb2QgL2ZpbmQgYnkgcmVwbGFjaW5nICd5JyBhcmd1bWVudC8NCmdncGxvdChwcmljZXMsIGFlcyhYMSwgWDQpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wNy0wMSIsIFgxIDwgIjIwMTgtMDgtMTAiKSAlPiUgc2VsZWN0KFgxLCBYNCkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYNCkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFg0KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFg0LnksIGNvbCA9IFg0LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9yYW4yIDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYNC54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFg5KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTgtMDYtMjUiLCBYMSA8ICIyMDE4LTA3LTEwIikgJT4lIHNlbGVjdChYMSwgWDkpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDkpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYOSkgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYOS55LCBjb2wgPSBYOS54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fcmFuMyA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDkueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYMTIpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgYXBwcm94aW1hdGUgZGF0ZSBhbmQgY2hvb3NlIG9ubHkgcmVsZXZhbnQgY29sdW1ucw0KcHJpY2VfZGYgPC0gcHJpY2VzICU+JSBmaWx0ZXIoWDEgPiAiMjAxOC0wNi0yNSIsIFgxIDwgIjIwMTgtMDctMTAiKSAlPiUgc2VsZWN0KFgxLCBYOSkNCg0KIyBWaXN1YWxpemUgaXQgdG8gY29uZmlybSANCmdncGxvdChwcmljZV9kZiwgYWVzKFgxLCBYOSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBjb3JyZXNwb25kaW5nIHBpZWNlIG9mIG1hY2QgZGF0YWZyYW1lOg0KbWFjZF9kZiA8LSBtYWNkICU+JSBzZWxlY3QoWDEsIFg5KSAlPiUgaW5uZXJfam9pbihwcmljZV9kZiwgYnkgPSBjKCJYMSIgPSAiWDEiKSkNCg0KIyBWaXN1YWxpemUgYm90aCB0aGluZ3MgdG9nZXRoZXINCmdncGxvdChtYWNkX2RmLCBhZXMoWDEsIFg5LnksIGNvbCA9IFg5LngpKStnZW9tX2xpbmUoKQ0KDQojIHRyYW5zZm9ybSB0byBtYXRyaXgsIG51bWJlciBvZiBjb2x1bW5zIHdpbGwgY29ycmVzcG9uZCB0byBtb2RlbCBzZW5zaXRpdml0eSBlLmcuIDEwMCBjb2x1bW5zIH4gMjQgSG91cnMNCm1hY2RfbV9yYW4zIDwtIG1hY2RfZGYgJT4lIHNlbGVjdChYOS54KSAlPiUgdG9fbSg2NCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCm1hY2RfbV9yYW4xIDwtIHRyYW5zZm9ybShtYWNkX21fcmFuMSwgTV9UID0gIlJBTiIpIA0KbWFjZF9tX3JhbjIgPC0gdHJhbnNmb3JtKG1hY2RfbV9yYW4yLCBNX1QgPSAiUkFOIikgDQptYWNkX21fcmFuMyA8LSB0cmFuc2Zvcm0obWFjZF9tX3JhbjMsIE1fVCA9ICJSQU4iKSANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIC0tLS0tLS0tLS0gIyA2LiBTaWRld2F5cyB2b2xhdGlsZSwgUkFWIC0tLS0tLS0tLS0tLS0tLQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2hvb3NlIHRoZSBhc3NldCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGVyaW9kIC9maW5kIGJ5IHJlcGxhY2luZyAneScgYXJndW1lbnQvDQpnZ3Bsb3QocHJpY2VzLCBhZXMoWDEsIFgyKSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGFwcHJveGltYXRlIGRhdGUgYW5kIGNob29zZSBvbmx5IHJlbGV2YW50IGNvbHVtbnMNCnByaWNlX2RmIDwtIHByaWNlcyAlPiUgZmlsdGVyKFgxID4gIjIwMTgtMDItMDEiLCBYMSA8ICIyMDE4LTA0LTAxIikgJT4lIHNlbGVjdChYMSwgWDIpDQoNCiMgVmlzdWFsaXplIGl0IHRvIGNvbmZpcm0gDQpnZ3Bsb3QocHJpY2VfZGYsIGFlcyhYMSwgWDIpKStnZW9tX2xpbmUoKQ0KDQojIEV4dHJhY3QgY29ycmVzcG9uZGluZyBwaWVjZSBvZiBtYWNkIGRhdGFmcmFtZToNCm1hY2RfZGYgPC0gbWFjZCAlPiUgc2VsZWN0KFgxLCBYMikgJT4lIGlubmVyX2pvaW4ocHJpY2VfZGYsIGJ5ID0gYygiWDEiID0gIlgxIikpDQoNCiMgVmlzdWFsaXplIGJvdGggdGhpbmdzIHRvZ2V0aGVyDQpnZ3Bsb3QobWFjZF9kZiwgYWVzKFgxLCBYMi55LCBjb2wgPSBYMi54KSkrZ2VvbV9saW5lKCkNCg0KIyB0cmFuc2Zvcm0gdG8gbWF0cml4LCBudW1iZXIgb2YgY29sdW1ucyB3aWxsIGNvcnJlc3BvbmQgdG8gbW9kZWwgc2Vuc2l0aXZpdHkgZS5nLiAxMDAgY29sdW1ucyB+IDI0IEhvdXJzDQptYWNkX21fcmF2MSA8LSBtYWNkX2RmICU+JSBzZWxlY3QoWDIueCkgJT4lIHRvX20oNjQpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIENob29zZSB0aGUgYXNzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIHBlcmlvZCAvZmluZCBieSByZXBsYWNpbmcgJ3knIGFyZ3VtZW50Lw0KZ2dwbG90KHByaWNlcywgYWVzKFgxLCBYOSkpK2dlb21fbGluZSgpDQoNCiMgRXh0cmFjdCBhcHByb3hpbWF0ZSBkYXRlIGFuZCBjaG9vc2Ugb25seSByZWxldmFudCBjb2x1bW5zDQpwcmljZV9kZiA8LSBwcmljZXMgJT4lIGZpbHRlcihYMSA+ICIyMDE3LTExLTAxIiwgWDEgPCAiMjAxNy0xMi0wMSIpICU+JSBzZWxlY3QoWDEsIFg5KQ0KDQojIFZpc3VhbGl6ZSBpdCB0byBjb25maXJtIA0KZ2dwbG90KHByaWNlX2RmLCBhZXMoWDEsIFg5KSkrZ2VvbV9saW5lKCkNCg0KIyBFeHRyYWN0IGNvcnJlc3BvbmRpbmcgcGllY2Ugb2YgbWFjZCBkYXRhZnJhbWU6DQptYWNkX2RmIDwtIG1hY2QgJT4lIHNlbGVjdChYMSwgWDkpICU+JSBpbm5lcl9qb2luKHByaWNlX2RmLCBieSA9IGMoIlgxIiA9ICJYMSIpKQ0KDQojIFZpc3VhbGl6ZSBib3RoIHRoaW5ncyB0b2dldGhlcg0KZ2dwbG90KG1hY2RfZGYsIGFlcyhYMSwgWDkueSwgY29sID0gWDkueCkpK2dlb21fbGluZSgpDQoNCiMgdHJhbnNmb3JtIHRvIG1hdHJpeCwgbnVtYmVyIG9mIGNvbHVtbnMgd2lsbCBjb3JyZXNwb25kIHRvIG1vZGVsIHNlbnNpdGl2aXR5IGUuZy4gMTAwIGNvbHVtbnMgfiAyNCBIb3Vycw0KbWFjZF9tX3JhdjIgPC0gbWFjZF9kZiAlPiUgc2VsZWN0KFg5LngpICU+JSB0b19tKDY0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQptYWNkX21fcmF2MSA8LSB0cmFuc2Zvcm0obWFjZF9tX3JhdjEsIE1fVCA9ICJSQVYiKQ0KbWFjZF9tX3JhdjIgPC0gdHJhbnNmb3JtKG1hY2RfbV9yYXYyLCBNX1QgPSAiUkFWIikNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyBDb21iaW5lIGFsbCBvZiB0aGF0IDopDQptYWNkX01MMiA8LSByYmluZChtYWNkX21fYnVuMSxtYWNkX21fYnVuMixtYWNkX21fYnVuMyxtYWNkX21fYnVuNCxtYWNkX21fYnVuNSwNCiAgICAgICAgICAgICAgICAgIG1hY2RfbV9idXYxLG1hY2RfbV9idXYyLG1hY2RfbV9idXYzLG1hY2RfbV9idXY0LG1hY2RfbV9idXY1LG1hY2RfbV9idXY2LG1hY2RfbV9idXY3LG1hY2RfbV9idXY4LG1hY2RfbV9idXY5LA0KICAgICAgICAgICAgICAgICAgbWFjZF9tX2JlbjEsbWFjZF9tX2JlbjIsbWFjZF9tX2JlbjMsbWFjZF9tX2JlbjQsbWFjZF9tX2JlbjUsDQogICAgICAgICAgICAgICAgICBtYWNkX21fYmV2MSxtYWNkX21fYmV2MixtYWNkX21fYmV2MyxtYWNkX21fYmV2NCxtYWNkX21fYmV2NSxtYWNkX21fYmV2NixtYWNkX21fYmV2NywNCiAgICAgICAgICAgICAgICAgIG1hY2RfbV9yYW4xLG1hY2RfbV9yYW4yLG1hY2RfbV9yYW4zLA0KICAgICAgICAgICAgICAgICAgbWFjZF9tX3JhdjEsbWFjZF9tX3JhdjIpDQoNCiMjIyBOT1RFIE51bWJlciBvZiByb3dzIE1hdHJpY2VzIG5lZWRzIHRvIGJlIHJvdWdobHkgZXF1YWwNCg0KIyBPcHRpb25hbGx5IHJlY29yZCBkYXRhIGludG8gdGhlIGZvbGRlcg0KaWYoIWRpci5leGlzdHMoZmlsZS5wYXRoKGdldHdkKCksIl9EQVRBL2RhdGFfaW5pdGlhbCIpKSl7DQogIGRpci5jcmVhdGUoZmlsZS5wYXRoKGdldHdkKCksIl9EQVRBL2RhdGFfaW5pdGlhbCIpKQ0KICB3cml0ZV9yZHMobWFjZF9NTDIsIGZpbGUucGF0aChnZXR3ZCgpLCJfREFUQS9kYXRhX2luaXRpYWwiLCAibWFjZF9NTDIucmRzIikpDQp9DQogIA0KDQojIyBWaXN1YWxpemUgbmV3IG1hdHJpeCBpbiAzRA0KcGxvdF9seSh6ID0gYXMubWF0cml4KG1hY2RfTUwyWywxOjY0XSksIHR5cGUgPSAic3VyZmFjZSIpDQoNCiMjIyMgRW5kDQpgYGANCg0KIyMgR2VuZXJhdGUgbW9kZWwNCg0KRm9sZGVyIF9QUk9EIGNvbnRhaW5zIHNjcmlwdCAwMl9CdWlsZE1vZGVsLlIgdGhhdCBjYW4gYmUgdXNlZCB0byBidWlsZCBhIG1vZGVsDQoNCiMjIENsYXNzaWZ5IGN1cnJlbnQgbWFya2V0IHR5cGUNCg0KRm9sZGVyIF9QUk9EIGNvbnRhaW5zIHNjcmlwdCAwM19TY29yZV9EYXRhLlIgdGhhdCBjYW4gYmUgdXNlZCB0byBzY29yZSBuZXcgZGF0YQ0KDQojIyBDb25jbHVzaW9uDQoNClNjcmlwdHMgY291bGQgYmUgYXV0b21hdGVkIHRvIHJ1biBhbmQgcHJlZGljdCBjdXJyZW50IG1hcmtldCB0eXBlLiBJbiBtYW55IG9jY2FzaW9ucyBjb25maWRlbmNlIG9mIHByZWRpY3Rpb25zIHdpbGwgYmUgbG93IHRoaXMgY2FuIGJlIHVzZWQgdG8gZmlsdGVyIGJhZCBwcmVkaWN0aW9ucw0KDQo=